package com.example.flowerpcback.services;

import com.alibaba.fastjson.JSONObject;
import com.example.flowerpcback.dto.*;
import com.example.flowerpcback.exception.BusinessException;
import com.example.flowerpcback.exception.BusinessExceptionCode;
import com.example.flowerpcback.mapper.MenusMapper;
import com.example.flowerpcback.mapper.RolesMapper;
import com.example.flowerpcback.mapper.UserMapper;
import com.example.flowerpcback.mapper.UserMyMapper;
import com.example.flowerpcback.req.RolesMenusReq;
import com.example.flowerpcback.req.RolesReq;
import com.example.flowerpcback.req.UserReq;
import com.example.flowerpcback.resp.*;
import com.example.flowerpcback.utils.CopyUtil;
import com.example.flowerpcback.utils.MenuUtil;
import com.example.flowerpcback.utils.SnowFlake;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class UserService {
    private static final Logger LOG = LoggerFactory.getLogger(UserService.class);

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private UserMapper userMapper;

    @Resource
    private UserMyMapper userMyMapper;

    @Resource
    private SnowFlake snowFlake;

    @Resource
    private CaptchaService captchaService;

    @Resource
    private RolesMenusService rolesMenusService;

    @Resource
    private MenusMapper menusMapper;

    public UserResp login(UserReq req, String sessionId){
        LOG.info(req.getUsername());
        UserExample userExample = new UserExample();
        UserExample.Criteria criteria = userExample.createCriteria();
        criteria.andUsernameEqualTo(req.getUsername());
        criteria.andPasswordEqualTo(req.getPassword());

        List<User> userList = userMapper.selectByExample(userExample);

        if(!captchaService.validateCaptcha(sessionId,req.getCode())){
            throw new BusinessException(BusinessExceptionCode.CODE_ERROR);
        } else if(userList.isEmpty()){
            throw new BusinessException(BusinessExceptionCode.LOGIN_USER_ERROR);
        }else{
            User user = userList.get(0);
            Long roleId = user.getRoleid();
            RolesMenusReq rolesMenusReq = new RolesMenusReq();
            rolesMenusReq.setRoleId(roleId);
            List<RolesMenusResp> rolesMenus = rolesMenusService.list(rolesMenusReq);

            List<List<MenusResp>> listMenusResp = formatterMenus(rolesMenus);
            UserResp loginUserResp = new CopyUtil().copy(user, UserResp.class);

            loginUserResp.setRolesMenus(listMenusResp.get(0));
            loginUserResp.setRolesBtns(listMenusResp.get(1));

            Long id = snowFlake.nextId();
            redisTemplate.opsForValue().set(id,JSONObject.toJSONString(user),3600*24, TimeUnit.SECONDS);
            loginUserResp.setToken(id);

            return loginUserResp;
        }


    }

    public List<List<MenusResp>> formatterMenus(List<RolesMenusResp> rolesMenusData){
        MenusExample menusExample = new MenusExample();

        List<Menus> menusData = menusMapper.selectByExample(menusExample);

        List<Menus> menuResult = new ArrayList<>();
        List<Menus> btnResult = new ArrayList<>();

        for (RolesMenusResp rolesMenus:rolesMenusData){
            for (Menus menus:menusData){
                if(rolesMenus.getMenuId().equals(menus.getId())){
                    if(menus.getType().equals("1") || menus.getType().equals("2")){
                        menuResult.add(menus);
                    }else{
                        btnResult.add(menus);
                    }
                }
            }
        }

        List<MenusResp> btnRep = new CopyUtil().copyList(btnResult,MenusResp.class);
        List<MenusResp> menusResp = new CopyUtil().copyList(menuResult,MenusResp.class);
        List<MenusResp> res = new ArrayList<>();
        for (MenusResp menu : menusResp){
            if(menu.getParentid() == null) {
                menu.setChildren(new MenuUtil().findChilds(menu.getId(),menusResp));
                res.add(menu);
            }
        }

        List<List<MenusResp>>  menusBtnsMenus = new ArrayList<>();

        menusBtnsMenus.add(res);
        menusBtnsMenus.add(btnRep);

        return menusBtnsMenus;
    }

    public void logout(String token){
        redisTemplate.delete(token);
    }

    public PageResp<UserResp> list(UserReq req) {
        UserExample userExample = new UserExample();
        UserExample.Criteria criteria = userExample.createCriteria();
        if(req.getRoleid() != null) {
            criteria.andRoleidEqualTo(req.getRoleid());
        }

        PageHelper.startPage(req.getPage(),req.getSize());

        List<User> userList = userMapper.selectByExample(userExample);

        PageInfo<User> pageInfo = new PageInfo<>(userList);
        PageResp<UserResp> pageResp = new PageResp<>();
        pageResp.setTotal(pageInfo.getTotal());
        pageResp.setPages(pageInfo.getPages());

        List<UserResp> userRespList = new CopyUtil().copyList(userList,UserResp.class);

        pageResp.setList(userRespList);

        return pageResp;
    }

    public PageResp<UserResp> myList(UserReq req) {
        PageHelper.startPage(req.getPage(),req.getSize());

        List<UserResp> userList = userMyMapper.selectUser(req.getRoleid(),req.getNickname(),req.getCreateTime(),req.getUpdateTime());

        PageInfo<UserResp> pageInfo = new PageInfo<>(userList);
        PageResp<UserResp> pageResp = new PageResp<>();
        pageResp.setTotal(pageInfo.getTotal());
        pageResp.setPages(pageInfo.getPages());

        pageResp.setList(userList);

        return pageResp;
    }

    public User save(UserReq req){

        User user = new CopyUtil().copy(req, User.class);
        if(req.getId() == null){
            user.setCreateTime(new Date());
            user.setUpdateTime(new Date());
            Long id = snowFlake.nextId();
            req.setId(id);
            userMapper.insert(user);
        }else {
            user.setUpdateTime(new Date());
            userMapper.updateByPrimaryKeySelective(user);
        }

        return user;

    }

    public void delete(UserReq req){
        userMapper.deleteByPrimaryKey(req.getId());
    }
}
